﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Xml.Linq;
using System.Data ;

using DbSharp.Framework.Driver;

namespace DbSharp.Framework.DbObject
{

    /// <summary>
    /// This class is designed to handle one procedure declaration section in procedures.xml
    /// </summary>
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class ProcedureDeclaration:IStatementDeclaration
    {
        #region Private members
        
        private List<StatementArgument> m_ListArgument;
        
        #endregion


        #region Public properties/methods

        public string ProcedureName { get; set; }

        public string Namespace { get; set; }


        /// <summary>
        /// Return the full qualified access name of the stored procedure 
        /// </summary>
        /// <returns></returns>
        public string GetAccessFullName()
        {
            string procedureFullName = string.Empty;
            if (string.IsNullOrEmpty(Namespace) == false)
                procedureFullName = procedureFullName + Namespace + ".";
            procedureFullName = procedureFullName + ProcedureName;

            return procedureFullName;
        }


        public override string ToString()
        {
            return "<" + Alias + ">"+GetAccessFullName();
        }



        #endregion


        #region IStatementDeclaration Members

        public string Alias { get; set; }
        public string Remark { get; set; }
        public string ConnectionString { get; set; }
        public string ConnectionProviderName { get; set; }
        public string CommandText
        {
            get { return GetAccessFullName(); }
        }
 
        public List<StatementArgument> ListArgument
        {
            get { return m_ListArgument; }
            set { m_ListArgument = value; }
        }

        public CommandType CommandType
        {
            get { return CommandType.StoredProcedure; }
        }

        public DbCommandExecuteType GetCommandExecuteType(ITestDataSource dataSource)
        {
            return StatementDeclarationExt.DetermineDbCmdExecuteType(dataSource, this.ListArgument);
        }


        public StatementArgument FindArgument(string argumentName)
        {
            string upperName = argumentName.Trim().ToUpper();
            upperName = StatementDeclarationExt.NormalizeArgumentName(ConnectionProviderName, ConnectionString, upperName);
            foreach (var arg in m_ListArgument)
            {
                if (arg.Name.ToUpper() == upperName)
                    return arg;
            }
            return null;
        }


        public IStatementDeclaration CloneStatement()
        {
            ProcedureDeclaration newProcObj = new ProcedureDeclaration();
            newProcObj.Alias = this.Alias; 
            newProcObj.ConnectionProviderName = this.ConnectionProviderName;
            newProcObj.ConnectionString = this.ConnectionString;
            newProcObj.Namespace = this.Namespace;
            newProcObj.ProcedureName = this.ProcedureName;
            newProcObj.Remark = this.Remark;
             
            List<StatementArgument> listArg = new List<StatementArgument>();
            foreach (var arg in this.ListArgument)
            {
                var item = arg.CloneArgument();
                listArg.Add(item);
            }
            newProcObj.ListArgument = listArg; 

            return newProcObj;
        }
        #endregion
    }
}
